[iOS 7] [iBeacon] Mac を Beacon 端末にする
2014/11/06 更新
CBPeripheralManager が Yosemite (OS X 10.10) では動かないバグがあるようです。
そのため Mac で試す場合、Mavericks 以前の OS X バージョンで実行する必要があります。
http://stackoverflow.com/questions/25492316/cbperipheralmanager-startadvertising-not-working-on-os-x-yosemite
現在既にバグレポートが報告されているようなので、
次のバージョンでFixされることを期待するしかないようです。
情報を提供くださいました ppia さん、誠にありがとうございます!
2014/11/19 更新
Yosemite (OS X 10.10) で CBPeripheralManager を動作させたい場合、
Bluetooth の USB ドングルを利用すると良いようです。
http://stackoverflow.com/questions/25492316/cbperipheralmanager-startadvertising-not-working-on-os-x-yosemite
http://www.planex.co.jp/products/bt-micro4/
情報を提供くださいました Yuuki NISHIYAMA さん、誠にありがとうございます!
Mac を Beacon にしたい!
iBeacon Advent Calendar 2013 の19日目を担当します!
最近何かと話題の iBeacon。先日、弊社で開催した iBeacon 勉強会も満席・大盛況でした。足を運んでいただいたかた、Ust を御覧頂いたかた、誠にありがとうございましたm(_ _)m
【iOS勉強会】iBeaconでできること – Developers.IO Meetup 02 を開催しました #cmdevio | Developers.IO
そんな iBeacon ですが、アプリを実装しテストするためには iOS 7 の端末(セントラル側)と Beacon となる端末(ペリフェラル側)が必要です。会社でやるならまだしも、個人で開発する場合 iPhone を使っているなら1台は用意できたとしても、更にもう1台用意するのは大変かも知れません。。
そんなときはいまお使いの Mac を Beacon 端末にしましょう。ということで本記事では Beacon になる Mac アプリの作りかたを解説します!といっても似通った記事は多く出回っているので、Mac アプリの作り始めから順を追って解説してみたいと思います。下記の記事も参考になるので、こちらも併せてお読みください。
- Mavericks as an iBeacon | Blended Cocoa
- 【iBeacon】部屋に帰ると「おかえり」って言ってくれるiPhoneアプリを作る【iMac→iPhone】 | Tech Tech walker
- MacをiBeaconにする ステータスバー常駐アプリXBeaconを作ってみた | ReDo
Mac アプリを作ってみる
まず Xcode を起動して新規プロジェクトを作りましょう。種類は OSX の CocoaApplication を選びます。
ProductName とか色々適当に作ります。iOS アプリを作る場合と同じ感じですね。
プロジェクトができたので、試しに起動してみましょう。
スッカラカンのアプリが起動しました。とりあえずアプリの起動は確認できたということで。
次に Bluetooth を使うために IOBluetooth.framework を追加します。iOS では CoreBluetooth.framework を使いますが、Mac の場合は IOBluetooth.framework を使います。
次にアドバタイズ用のデータを格納するクラスを作ります。iOS では CLBeaconRegion クラスがありますが、同様のクラスはないので作らなければいけません。
MBCBeaconAdvertisementData.h
#import <Foundation/Foundation.h> @interface MBCBeaconAdvertisementData : NSObject @property (strong,nonatomic) NSUUID *proximityUUID; @property (assign,nonatomic) uint16_t major; @property (assign,nonatomic) uint16_t minor; @property (assign,nonatomic) int8_t measuredPower; - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(uint16_t)major minor:(uint16_t)minor measuredPower:(int8_t)power; - (NSDictionary *)beaconAdvertisement; @end
MBCBeaconAdvertisementData.m
#import "MBCBeaconAdvertisementData.h" @implementation MBCBeaconAdvertisementData - (id)initWithProximityUUID:(NSUUID *)proximityUUID major:(uint16_t)major minor:(uint16_t)minor measuredPower:(int8_t)power { self = [super init]; if (self) { _proximityUUID = proximityUUID; _major = major; _minor = minor; _measuredPower = power; } return self; } - (NSDictionary *)beaconAdvertisement { NSString *beaconKey = @"kCBAdvDataAppleBeaconKey"; unsigned char advertisementBytes[21] = {0}; [self.proximityUUID getUUIDBytes:(unsigned char *)&advertisementBytes]; advertisementBytes[16] = (unsigned char)(self.major >> 8); advertisementBytes[17] = (unsigned char)(self.major & 255); advertisementBytes[18] = (unsigned char)(self.minor >> 8); advertisementBytes[19] = (unsigned char)(self.minor & 255); advertisementBytes[20] = self.measuredPower; NSMutableData *advertisement = [NSMutableData dataWithBytes:advertisementBytes length:21]; return [NSDictionary dictionaryWithObject:advertisement forKey:beaconKey]; }
あとは AppDelegate にペリフェラルになる処理をコーディングしていきます。
MBCAppDelegate.h
#import <Cocoa/Cocoa.h> #import <IOBluetooth/IOBluetooth.h> #import "MBCBeaconAdvertisementData.h" @interface MBCAppDelegate : NSObject <NSApplicationDelegate, CBPeripheralManagerDelegate> @property (assign) IBOutlet NSWindow *window; @property (strong, nonatomic) CBPeripheralManager *manager; @end
MBCAppDelegate.m
#import "MBCAppDelegate.h" @implementation MBCAppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // CBPeripheralManagerを初期化 self.manager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { // Bluetoothがオンのときにアドバタイズする if (peripheral.state == CBPeripheralManagerStatePoweredOn) { // UUIDを適当に作成(uuidgenコマンドで生成する) NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"1E21BCE0-7655-4647-B492-A3F8DE2F9A02"]; // アドバタイズ用のデータを作成 MBCBeaconAdvertisementData *beaconData = [[MBCBeaconAdvertisementData alloc] initWithProximityUUID:proximityUUID major:1 minor:1 measuredPower:-58]; // アドバタイズ開始 [peripheral startAdvertising:beaconData.beaconAdvertisement]; } } @end
以上で実装完了です!アプリを起動すると iOS 7 の iBeacon アプリで検知できる Beacon になります。iBeacon アプリのほうは先日の勉強会で共有したアプリで試してみるといい感じに検知すると思います(もちろん、UUIDは合わせましょう!)。
まとめ
こんな感じで iOS 7 の端末が一台しかなくても iBeacon で遊ぶことができます。たくさんの Beacon 端末が必要な場合も、Mac も併用するとさらに多くの Beacon を作ることができますね!